package com.asen.commons.utils;

import com.asen.commons.core.json.MultiDateDeserializer;
import com.asen.commons.core.base.model.JsonObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

public class JsonMapper {
    private static ObjectMapper objectMapper = new ObjectMapper();

    public JsonMapper() {
    }

    public static <T> T json2obj(String json, Class<T> clazz) {
        if (!StringUtils.isEmpty(json) && clazz != null) {
            try {
                return clazz.equals(String.class) ? (T) json : objectMapper.readValue(json, clazz);
            } catch (Exception var3) {
                throw new IllegalArgumentException(var3);
            }
        } else {
            return null;
        }
    }

    public static <T> T json2obj(String json, TypeReference<T> typeReference) {
        if (!StringUtils.isEmpty(json) && typeReference != null) {
            try {
                return typeReference.getType().equals(String.class) ? (T) json : objectMapper.readValue(json, typeReference);
            } catch (Exception var3) {
                throw new IllegalArgumentException(var3);
            }
        } else {
            return null;
        }
    }

    public static String obj2json(Object obj) {
        if (obj == null) {
            return null;
        } else {
            try {
                return objectMapper.writeValueAsString(obj);
            } catch (Exception var2) {
                throw new IllegalArgumentException(var2);
            }
        }
    }

    public static byte[] obj2bytes(Object obj) {
        if (obj == null) {
            return null;
        } else {
            try {
                return objectMapper.writeValueAsBytes(obj);
            } catch (Exception var2) {
                throw new IllegalArgumentException(var2);
            }
        }
    }

    public static JsonObject json2map(String json) {
        if (StringUtils.isEmpty(json)) {
            return null;
        } else {
            try {
                return (JsonObject)objectMapper.readValue(json, JsonObject.class);
            } catch (Exception var2) {
                throw new IllegalArgumentException(var2);
            }
        }
    }

    public static <T> T map2obj(Map map, Class<T> clazz) {
        return map != null && !map.isEmpty() ? objectMapper.convertValue(map, clazz) : null;
    }

    public static <T> JsonObject obj2map(T obj) {
        return obj == null ? null : (JsonObject)objectMapper.convertValue(obj, JsonObject.class);
    }

    public static String map2Json(Map map) {
        if (map != null && !map.isEmpty()) {
            try {
                return objectMapper.writeValueAsString(map);
            } catch (Exception var2) {
                throw new IllegalArgumentException(var2);
            }
        } else {
            return null;
        }
    }

    public static <T> List<T> json2list(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return null;
        } else {
            try {
                JavaType javaType = getCollectionType(ArrayList.class, clazz);
                return (List)objectMapper.readValue(json, javaType);
            } catch (IOException var3) {
                throw new IllegalArgumentException(var3);
            }
        }
    }

    public static <T> List<T> obj2list(Collection collection, Class<T> clazz) {
        if (collection != null && !collection.isEmpty()) {
            String json = obj2json(collection);
            return json2list(json, clazz);
        } else {
            return null;
        }
    }

    public static <T> String list2json(List<T> list) {
        if (list != null && !list.isEmpty()) {
            try {
                return objectMapper.writeValueAsString(list);
            } catch (Exception var2) {
                throw new IllegalArgumentException(var2);
            }
        } else {
            return null;
        }
    }

    public static JsonObject json2mapDeeply(String json) {
        if (StringUtils.isEmpty(json)) {
            return null;
        } else {
            try {
                return json2MapRecursion(json, objectMapper);
            } catch (Exception var2) {
                throw new IllegalArgumentException(var2);
            }
        }
    }

    private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        } else {
            List<Object> list = (List)mapper.readValue(json, List.class);
            Iterator var3 = list.iterator();

            while(var3.hasNext()) {
                Object obj = var3.next();
                if (obj != null && obj instanceof String) {
                    String str = (String)obj;
                    if (str.startsWith("[")) {
                        json2ListRecursion(str, mapper);
                    } else if (obj.toString().startsWith("{")) {
                        json2MapRecursion(str, mapper);
                    }
                }
            }

            return list;
        }
    }

    private static JsonObject json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        } else {
            JsonObject map = (JsonObject)mapper.readValue(json, JsonObject.class);
            Iterator var3 = map.entrySet().iterator();

            while(var3.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry)var3.next();
                Object obj = entry.getValue();
                if (obj != null && obj instanceof String) {
                    String str = (String)obj;
                    if (str.startsWith("[")) {
                        List<?> list = json2ListRecursion(str, mapper);
                        map.put(entry.getKey(), list);
                    } else if (str.startsWith("{")) {
                        Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
                        map.put(entry.getKey(), mapRecursion);
                    }
                }
            }

            return map;
        }
    }

    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    static {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        objectMapper.setFilterProvider((new SimpleFilterProvider()).setFailOnUnknownId(false));
        JavaTimeModule timeModule = new JavaTimeModule();
        timeModule.addDeserializer(Date.class, new MultiDateDeserializer());
        objectMapper.registerModules(timeModule, new ParameterNamesModule(), new Jdk8Module());
    }
}
